<script setup>
import { reactive, ref, toRaw, watch } from 'vue';

import { 
  getCommunications, createDevice, 
  getDeviceDetail, modifyDevice 
} from "@/api/device";

const visible = defineModel("visible")

const emits = defineEmits(["submit"])

const props = defineProps({
  no: {
    type: String,
    default: null
  },
  readonly: {
    type: Boolean,
    default: false
  }
})

const cascaderProps = {emitPath: false}
const devInterfaceType = ref("net")

const defaultInfo = {
  name: "",
  no: "",
  interface: null,
  communicationId: null,
  remark: null
}
const info = reactive({...defaultInfo})

// 获取系统可用的串口列表
const serials = ref([])

// 串口选择数据缓存
const selectCom = ref(null)
// 以太网数据缓存
const netInfo = reactive({
  host: null,
  port: null
})

// 获取系统可用的协议列表
const communications = ref([])
getCommunications().then(res => {
  if (res.code === 200) {
    communications.value = res.data
  }
})

watch(() => props.no, val => {
  if (!val) {
    Object.assign(info, defaultInfo)
  } else {
    getDeviceDetail(val).then(res => {
      if (res.code === 200) {
        Object.assign(info, res.data)
        Object.assign(netInfo, res.data.interface)
      }
    })
  }
})

// 提交数据
function submit() {
  const data = toRaw(info)
  data.interface = toRaw(netInfo)
  if (props.no) {
    ElMessageBox.confirm("确认修改设备信息吗？", "警告", {
      type: "warning",
      confirmButtonText: "确定",
      cancelButtonText: "取消"
    }).then(() => {
      modifyDevice(props.no, data).then(res => {
        if (res.code === 200) {
          ElMessage.success("修改成功")
          visible.value = false
          emits("submit")
        } else {
          ElMessage.error(res.msg)
        }
      }).catch(err => {
        console.log(err);
        ElMessage.error("网络异常，请稍后重试")
      })
    }).catch(() => {})
  } else {
    createDevice(data).then(res => {
      if (res.code === 200) {
        ElMessage.success("创建成功")
        visible.value = false
        emits("submit")
      } else {
        ElMessage.error(res.msg)
      }
    }).catch(err => {
      console.log(err);
      ElMessage.error("网络异常，请稍后重试")
    })
  }
}
</script>

<template>
  <el-dialog 
    :title="props.no ? `修改 ${info.name} 信息` : '添加新设备'"
    v-model="visible" 
    width="560px"
  >
    <el-form label-width="72px">
      <el-form-item label="设备名称">
        <el-input v-model="info.name" placeholder="请输入设备名称" />
      </el-form-item>
      <el-form-item label="设备编号">
        <el-input v-model="info.no" placeholder="请输入设备编号" />
      </el-form-item>
      <el-form-item label="通讯接口">
        <el-select v-model="devInterfaceType" placeholder="请选择硬件通讯接口">
          <el-option label="串行通讯" value="com" />
          <el-option label="以太网" value="net" />
        </el-select>
      </el-form-item>
      <el-form-item v-if="devInterfaceType === 'com'" label="COM">
        <el-select v-model="selectCom" placeholder="请选择串口号">
          <el-option 
            v-for="serial in serials" :key="serial.port" 
            :label="serial.name" :value="serial.port"
          />
        </el-select>
      </el-form-item>
      <el-form-item v-else-if="devInterfaceType === 'net'" label="IP地址">
        <div>
          <el-input v-model="netInfo.host" placeholder="请输入设备IP地址" style="width: 280px;" />
          <span class="ip-separator">:</span>
          <el-input v-model="netInfo.port" style="width: 146px;" placeholder="端口号" />
        </div>
      </el-form-item>
      <el-form-item label="通讯协议">
        <el-cascader v-model="info.communicationId" :props="cascaderProps" :options="communications" />
      </el-form-item>
      <el-form-item label="备注">
        <el-input v-model="info.remark" type="textarea" :rows="4" />
      </el-form-item>
    </el-form>
    <div class="btn-box">
      <el-button type="primary" @click="submit">{{ props.no ? '确认修改' : '创 建' }}</el-button>
      <el-button @click="visible = false">取 消</el-button>
    </div>
  </el-dialog>
</template>

<style lang="scss" scoped>
.btn-box {
  width: 100%;
  display: flex;
  justify-content: center;
}
.ip-separator {
  font-size: 14px;
  margin: 0 8px;
}
</style>
